package web.safety.action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import domain.entities.*;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.springframework.beans.factory.annotation.Autowired;
import services.*;
import web.CommonUtils;
import web.mails.MailUtils;

import javax.servlet.ServletContext;
import java.io.*;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: vgonzalez
 * Date: 30/08/12
 * Time: 14:59
 * To change this template use File | Settings | File Templates.
 */

@Namespace("/Safety/Document")
//@ResultPath("/")
public class DocumentController extends ActionSupport {
    private static final String TIPO_DOC_BODY = "Body";
    private static final String BODY_TEXT_FILE_PATH = "safetybody.txt";
    private static final String BODY_PROTOCOL_TEXT = "<protocols>";
    private static final String BODY_DOCUMENTS_TEXT = "<documents-drug>";
    private static final String BODY_ID_TEXT = "<id>";

    private List<Droga> drogaList;
    private List<Compromisopais> paisList;
    private List<Role> rolList;
    private DrogaService drogaService;
    private CompromisoPaisService paisService;
    private RoleCRUDService rolService;
    private SafetydocsService safetyService;
    private MiembroBmsProtocoloService miembroBmsProtocoloService;
    private InvestigadorProtocoloCentroService investigProtCentroService;
    private EnviosService enviosService;
    private Safetydocs safetydocs = new Safetydocs();
    private List<File> files = new ArrayList<File>();
    private List<DocumentType> tiposDocumentos;
    private List<String> filesContentType = new ArrayList<String>();
    private List<String> filesFileName = new ArrayList<String>();
    private List<Integer> rolesElegidos = new ArrayList<Integer>();
    private List<Integer> paisesElegidos = new ArrayList<Integer>();
    private List<MiembroBms> miembrosBms = new ArrayList<MiembroBms>();
    private List<Involucrado> involucrados = new ArrayList<Involucrado>();

    @Autowired
    public DocumentController(DrogaService drogaService, CompromisoPaisService paisService, RoleCRUDService rolService, SafetydocsService safetyService, EnviosService enviosService, MiembroBmsProtocoloService miembroBmsProtocoloService, InvestigadorProtocoloCentroService investigProtCentroService) {
        this.drogaService = drogaService;
        this.paisService = paisService;
        this.safetyService = safetyService;
        this.rolService = rolService;
        this.enviosService = enviosService;
        this.miembroBmsProtocoloService = miembroBmsProtocoloService;
        this.investigProtCentroService = investigProtCentroService;
        drogaList = drogaService.getDrogas();
        paisList = paisService.findAll();
        rolList = rolService.findAll();
        rolList.add(new Role(Role.ID_PRINCIPAL_INVESTIGATOR,Role.PRINCIPAL_INVESTIGATOR));
        rolList.add(new Role(Role.ID_SUB_INVESTIGATOR,Role.SUB_INVESTIGATOR));
        tiposDocumentos = DocumentType.getAllTypes();
    }

    @Action(value="main", results={
            @Result(name="success", location="/safety.document.create.tiles", type="tiles")
    })
    public String execute() {
        return SUCCESS;
    }

    private String getCuerpoMensaje(Collection<Envios> envios, Integer id, ServletContext context) throws Exception{
        String ruta = context.getRealPath(BODY_TEXT_FILE_PATH);
        FileInputStream fstream = new FileInputStream(ruta);
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
        String body = new String();
        String newLine = System.getProperties().getProperty("line.separator");
        String line;
        while ( (line = br.readLine()) != null){
            body = body + line + newLine;
        }
        in.close();
        br.close();
        fstream.close();

        String protocols = new String();
        Iterator<Protocolo> itProt = this.safetydocs.getDroga().getProtocolos().iterator();
        while(itProt.hasNext()){
            protocols += itProt.next().getId();
            if(itProt.hasNext())
                protocols += ", ";
        }

        int startProt = body.indexOf(BODY_PROTOCOL_TEXT);
        int finProt = startProt + BODY_PROTOCOL_TEXT.length();
        body = body.substring(0, startProt) + protocols + body.substring(finProt);

        int startDoc = body.indexOf(BODY_DOCUMENTS_TEXT);
        int finDoc = startDoc + BODY_DOCUMENTS_TEXT.length();

        String documentos = new String();
        Iterator<Envios> itEnvios = envios.iterator();
        while(itEnvios.hasNext()){
            documentos += getEnvioText(itEnvios.next(), newLine);
        }

        body = body.substring(0, startDoc) + documentos + body.substring(finDoc);

        int startId = body.indexOf(BODY_ID_TEXT);
        int finId = startId + BODY_ID_TEXT.length();

        body = body.substring(0, startId) + id.toString() + body.substring(finId);

        return body;
    }

    private String getEnvioText(Envios envio, String newLine) {
        if(envio.getType().equals("Body"))
            return "";
        String str = new String("Type: " + envio.getType() + newLine + "Name: " + envio.getName() + newLine);
        if(envio.getType().equals("IB")){
            str = str + "Version Date: " + CommonUtils.parseDDMMYYYY(envio.getVersionDate()) + newLine;
            str = str + "Cutoff Date: " + CommonUtils.parseDDMMYYYY(envio.getCutoffDate()) + newLine;
            if(envio.getReplaceNumber() != null){
                str = str + "Replaces previous version number: " + envio.getReplaceNumber();
                str = str + " dated " + CommonUtils.parseDDMMYYYY(envio.getReplaceDate());
                str += newLine;
            }
        }
        else if(envio.getType().equals("SUSAR")){
            str = str + "Event: " + envio.getEvent() + newLine;
            str = str + "Revision Date: " + CommonUtils.parseDDMMYYYY(envio.getRevisionDate()) + newLine;
            str = str + "Processed Date: " + CommonUtils.parseDDMMYYYY(envio.getProcessedDate()) + newLine;
            if(envio.getControlNumber() != null)
                str = str + "Control Number: " + envio.getControlNumber() + newLine;
        }
        else if(envio.getType().equals("Addendum")){
            str = str + "Version Date: " + CommonUtils.parseDDMMYYYY(envio.getVersionDate()) + newLine;
        }
        str += newLine;
        return str;
    }


    @Action(value="send", results={
            @Result(name="success", location="main", type="redirectAction")
    })
    public String send() {
        Map ctxSession = ActionContext.getContext().getSession();
        involucrados = (List<Involucrado>) ctxSession.get("involucrados");
        miembrosBms = (List<MiembroBms>) ctxSession.get("miembrosBms");

        Droga droga = drogaService.findById(safetydocs.getDroga().getId());
        safetydocs.setDroga(droga);

        Iterator<Envios> itEnv = safetydocs.getEnvioses().iterator();
        int i = 0;
        String tipos = new String();
        while(itEnv.hasNext()){
            Envios actual = itEnv.next();
            if(actual != null){
                actual.setSafetydocs(safetydocs);
                actual.setName(filesFileName.get(i));
                if(actual.getType() != null && !actual.getType().equals(TIPO_DOC_BODY)){
                    tipos = tipos + actual.getType() + " for " + safetydocs.getDroga().getDrugName() + "\n";
                }
                i++;
            }
        }

        Iterator<Integer> itCompr = paisesElegidos.iterator();
        while(itCompr.hasNext()){
            Integer actual = itCompr.next();
            safetydocs.getCountries().add(paisService.findById(actual));
        }

        Iterator<Integer> itRoles = rolesElegidos.iterator();
        safetydocs.setSentToPpalInv(false);
        safetydocs.setSentToSubInv(false);

        while(itRoles.hasNext()){
            Integer actual = itRoles.next();
            if(actual.equals(Role.ID_PRINCIPAL_INVESTIGATOR))
                safetydocs.setSentToPpalInv(true);
            else if(actual.equals(Role.ID_SUB_INVESTIGATOR))
                safetydocs.setSentToSubInv(true);
            else
                safetydocs.getRoles().add(rolService.getRoleById(actual));
        }

        safetydocs.setFecha(new Date());

        MailUtils mailUtils = new MailUtils(MailUtils.getAddressFromSafety(),MailUtils.getPassFromSafety());

        // Get system properties
        String subject = new String();

            /**Receptores */
        List<SafetyRecipient> recipients = new ArrayList<SafetyRecipient>();

        for (int j = 0; j < miembrosBms.size(); j++){
            MiembroBms actual = miembrosBms.get(j);
            String email = actual.getEmail();
            if(email != null){
                String [] emails = email.split(";");
                for(int k = 0; k< emails.length; k++){
                    if(!emails[k].equals("")){
                        SafetyRecipient recipient = new SafetyRecipient(safetydocs,actual.getName(), actual.getSurname(), emails[k]);
                        recipients.add(recipient);
                    }
                }
            }
        }
        for (int j = 0; j < involucrados.size(); j++){
            Involucrado actual = involucrados.get(j);
            String email = actual.getEmail();
            if(email != null){
                String [] emails = email.split(";");
                for(int k = 0; k< emails.length; k++){
                    if(!emails[k].equals("")){
                        SafetyRecipient recipient = new SafetyRecipient(safetydocs,actual.getNombre(), actual.getApellido(), emails[k]);
                        recipients.add(recipient);
                    }
                }
            }
        }

        List<String> toAddresses = new ArrayList<String>();
        toAddresses.add("vgonzalez@candoit.com.ar");

        List<String> bccAddresses = new ArrayList<String>();
        Iterator<SafetyRecipient> itRecip = recipients.iterator();
        while(itRecip.hasNext()){
            bccAddresses.add(itRecip.next().getEmail());
        }

      //  bccAddresses.add("monica.viard@bms.com");
      //  bccAddresses.add("diana.zubiri@bms.com");


        Iterator<String> itNames = filesFileName.iterator();

        while(itNames.hasNext()){
            String name = itNames.next();
            subject = subject + name + "_";
        }

        subject = subject.substring(0,subject.length() - 1);

        ServletContext context = ServletActionContext.getServletContext();

        try{
            safetydocs.setAsuntoMail(subject);
            safetydocs.setRecipients(recipients);
            safetyService.attachDirty(safetydocs);

            String body = getCuerpoMensaje(safetydocs.getEnvioses(), safetydocs.getId(), context);

            mailUtils.sendMail(subject, body, toAddresses, bccAddresses, files, filesFileName);
            /*(String subject, String body, List<String> toAddressesList, List<String> bccAddressesList,
                             List<File> attachments, List<String> attachmentsNames){*/
        }
        catch(Exception e){
            System.out.println(e.getMessage());
            System.out.println(e.getStackTrace().toString());
            //TODO
        }
        ctxSession = ActionContext.getContext().getSession();
        ctxSession.put("involucrados", null);
        ctxSession.put("miembrosBms", null);

        return SUCCESS;
    }

    public Safetydocs getSafetydocs() {
        return safetydocs;
    }

    public void setSafetydocs(Safetydocs safetydocs) {
        this.safetydocs = safetydocs;
    }

    public List<Droga> getDrogaList() {
        return drogaList;
    }

    public void setDrogaList(List<Droga> drogaList) {
        this.drogaList = drogaList;
    }

    public List<Compromisopais> getPaisList() {
        return paisList;
    }

    public void setPaisList(List<Compromisopais> paisList) {
        this.paisList = paisList;
    }

    public List<Role> getRolList() {
        return rolList;
    }

    public void setRolList(List<Role> rolList) {
        this.rolList = rolList;
    }

    public List<DocumentType> getTiposDocumentos() {
        return tiposDocumentos;
    }

    public void setTiposDocumentos(List<DocumentType> tiposDocumentos) {
        this.tiposDocumentos = tiposDocumentos;
    }

    public List<Integer> getRolesElegidos() {
        return rolesElegidos;
    }

    public void setRolesElegidos(List<Integer> rolesElegidos) {
        this.rolesElegidos = rolesElegidos;
    }

    public List<Integer> getPaisesElegidos() {
        return paisesElegidos;
    }

    public void setPaisesElegidos(List<Integer> paisesElegidos) {
        this.paisesElegidos = paisesElegidos;
    }

    public List<String> getFilesContentType() {
        return filesContentType;
    }

    public void setFilesContentType(List<String> filesContentType) {
        this.filesContentType = filesContentType;
    }

    public List<String> getFilesFileName() {
        return filesFileName;
    }

    public void setFilesFileName(List<String> filesFileName) {
        this.filesFileName = filesFileName;
    }

    public List<File> getFiles() {
        return files;
    }

    public void setFiles(List<File> files) {
        this.files = files;
    }

    public List<Involucrado> getInvolucrados() {
        return involucrados;
    }

    public void setInvolucrados(List<Involucrado> involucrados) {
        this.involucrados = involucrados;
    }

    public List<MiembroBms> getMiembrosBms() {
        return miembrosBms;
    }

    public void setMiembrosBms(List<MiembroBms> miembrosBms) {
        this.miembrosBms = miembrosBms;
    }

}